//wifi模块，用于获取当前IP地址
import wifi from '@ohos.wifi';
import socket from '@ohos.net.socket';
//日志模块
import { logger } from '../common/Logger'
import { GlobalVariable } from './GlobalVariable';

/**
 * 封装成UDP数据接收对象，在EntryAbility调用并开启服务，达到打开应用即可不断接收UDP协议数据的目的。
 *
 * 需要通过UDP接收的数据有：安全带是否正确佩戴的信息 {\"type\":\"belt\",\"id\":343,\"state\":0} 和  酒精检测信息：{"type":"mq3","id":0,"aout":558,"dout":1}
 * UDP数据丢失问题的安全带信息在后端进行处理和判断过。
 * 酒驾检测：如果dout==1则是酒驾，需要跳动图。当==0时取消动图，换为背景动图。
 * 安全带佩戴：当state==0时未佩戴，需要跳动图。当==1时取消动图，换为背景动图。不考虑多种异常行为同时出现的情况。
 */

//udp连接对象
let udp = socket.constructUDPSocketInstance();

//目标地址和端口
let targetAddr = {
  // address: '192.168.31.32', //要通信的 PC地址/
  address: '192.168.31.217', //要通信的 PC地址
  family: 1,
  // port: 10003 //UDP:7001/TCP:8001
  port: 7002 //UDP:7001/TCP:8001
}

export class UDPGetter {
  public message_send: string = 'hello'
  public message_recv: string = ''
  public status: string = '未连接'

  public localAddr = {
    address: this.resolveIP(wifi.getIpInfo().ipAddress),
  }

  udpInit() {
    //本地地址和端口
    udp.on('listening', () => {
      console.log("qqqqqqqq11111111111")

      logger.getInstance(this).debug("on udp listening success");
    });

    udp.on('message', value => {
      console.log("qqqqqqqq2222222222")
      this.message_recv = this.resolveArrayBuffer(value.message)
      logger.getInstance(this)
        .debug(`on udp message:${this.message_recv},remoteInfo:${JSON.stringify(value.remoteInfo)}`);
      let globalVariable = GlobalVariable.getInstance();

      //如果属于异常行为，就加到异常行为记录数组中。需要解析成需要的格式，方便展示在异常行为记录中。
      //currentData不需要解析改变结构，为了在DashBoard中正常判断。
      if (this.message_recv.includes("dout") && this.message_recv.charAt(this.message_recv.indexOf("dout") + 6) == "1") {
        let pro:number = this.message_recv.indexOf("2024");
        let aft:number = this.message_recv.indexOf("2024")+19;
        let resData:String = this.message_recv.slice(pro,aft);
        resData+=" 酒驾";
        console.log("sockethere1="+resData);

        //只记录确实是异常行为的数据。
        globalVariable.setdata(resData);
        globalVariable.setcurrentData(this.message_recv);

      } else if (this.message_recv.includes("BELT") && this.message_recv.charAt(this.message_recv.indexOf("STATE") + 7) == "0") {
        let pro:number = this.message_recv.indexOf("2024");
        let aft:number = this.message_recv.indexOf("2024")+19;
        let resData:String = this.message_recv.slice(pro,aft);
        resData+=" 未系安全带";
        console.log("sockethere2="+resData);

        //只记录确实是异常行为的数据。
        globalVariable.setdata(resData);
        globalVariable.setcurrentData(this.message_recv);

      } else if(this.message_recv.includes("look")){
        //左顾右盼
        let res: String = this.message_recv.slice(0,-4)
        res+="左顾右盼";
        console.log("sockethere2="+res);

        //只记录确实是异常行为的数据。
        globalVariable.setdata(res);
        globalVariable.setcurrentData(res);



      } else if(this.message_recv.includes("yawn")) {
        //打哈欠
        let res: String = this.message_recv.slice(0, -4)
        res += "打哈欠";
        console.log("sockethere2=" + res);

        //只记录确实是异常行为的数据。
        globalVariable.setdata(res);
        globalVariable.setcurrentData(res);



      } else if(this.message_recv.includes("sleep")) {
        //打瞌睡
        let res: String = this.message_recv.slice(0, -5)
        res += "打瞌睡";
        console.log("sockethere2=" + res);

        //只记录确实是异常行为的数据。
        globalVariable.setdata(res);
        globalVariable.setcurrentData(res);



      } else if(this.message_recv.includes("blink")) {
        //眨眼
        let res: String = this.message_recv.slice(0, -5)
        res += "眨眼";
        console.log("sockethere2=" + res);

        //只记录确实是异常行为的数据。
        globalVariable.setdata(res);
        globalVariable.setcurrentData(res);

      }



      console.log("socketglobalVariable.getcurrentData() =" + globalVariable.getcurrentData())
      console.log("socketglobalVariable.getdata() =" + globalVariable.getdata())
    });

    udp.on('close', () => {
      logger.getInstance(this).debug(`on udp close success`);
    });

    logger.getInstance(this).debug(`udpInit...`);
    //bind本地地址
    udp.bind({ address: this.localAddr.address, port: 7001, family: 1 })
      .then(() => {
        logger.getInstance(this).debug(`bind upd success`);
      }).catch((err) => {
      logger.getInstance(this).error(`bind upd failed ${JSON.stringify(err)}`);
    })

  }

  udpSend() {
    //查看状态
    udp.getState().then((data) => {
      logger.getInstance(this).debug(`====${JSON.stringify(data)}`)
      //如果已关闭，就重新初始化
      if (data.isClose) {
        this.udpInit()
      }
      //已绑定，就发送数据
      if (data.isBound) {
        udp.send(
          {
            data: this.message_send,
            address: { address: targetAddr.address, port: 10003, family: 1 }
          }
        )
          .then(() => {
            logger.getInstance(this).debug(`send success`);
          })
          .catch((error) => {
            logger.getInstance(this).error(`send failed ${typeof error.code}`);
          })
      }
    })
  }

  udpClose() {
    udp.off('message');
    udp.off('listening');
    udp.off('close');

    udp.close().then(() => {
      logger.getInstance(this).debug("udp.close success");
    }).catch((err) => {
      logger.getInstance(this).error(`udp.close error:${JSON.stringify(err)}`)
    })

  }


  //解析ArrayBuffer
  resolveArrayBuffer(message: ArrayBuffer): string {
    if (message instanceof ArrayBuffer) {
      let dataView = new DataView(message)
      logger.getInstance(this).debug(`length ${dataView.byteLength}`)
      let str = ""
      for (let i = 0; i < dataView.byteLength; ++i) {
        let c = String.fromCharCode(dataView.getUint8(i))
        if (c !== "\n") {
          str += c
        }
      }

      console.log("str1=" + str);
      return str;
    }
  }

  //解析本地IP,需要声明ohos.permission.GET_WIFI_INFO权限
  resolveIP(ip) {
    if (ip < 0 || ip > 0xFFFFFFFF) {
      throw ("The number is not normal!");
    }
    return (ip >>> 24) + "." + (ip >> 16 & 0xFF) + "." + (ip >> 8 & 0xFF) + "." + (ip & 0xFF);
  }
}